package tp_imag.service.impl;

import java.util.HashMap;
import java.util.Vector;

import org.apache.log4j.Logger;

public class Recorrido {

        static Logger logger = Logger.getLogger(Recorrido.class);
	
	private int arrayOrigen[][];
	private int ancho;
	private int alto;
	private int direccionX = 1; 
	private int direccionY = -1;
	private int longitud = 1;
	
	//Defino direcciones a tomar
	static final VectorDirector MOVER_ARRIBA 			= new VectorDirector( 0,-1);
	static final VectorDirector MOVER_ABAJO  			= new VectorDirector( 0, 1);
	static final VectorDirector MOVER_DERECHA 			= new VectorDirector( 1, 0);
	static final VectorDirector MOVER_IZQUIERDA			= new VectorDirector(-1, 0);
	static final VectorDirector MOVER_ARRIBA_DERECHA 	= new VectorDirector( 1,-1);
	static final VectorDirector MOVER_ARRIBA_IZQUIERDA 	= new VectorDirector(-1,-1);
	static final VectorDirector MOVER_ABAJO_DERECHA 	= new VectorDirector( 1, 1);
	static final VectorDirector MOVER_ABAJO_IZQUIERDA 	= new VectorDirector(-1, 1);
	static final VectorDirector NO_MOVER 				= new VectorDirector( 0, 0);
	
	static final HashMap secuenciaDireccion 	= new HashMap<Coordenada, Coordenada>();
	private VectorDirector ultimaDireccion = new VectorDirector(NO_MOVER);
	
	public Recorrido(int array[][], int ancho, int alto) {
		this.alto = alto;
		this.ancho = ancho;
		arrayOrigen = array;
		/*
		secuenciaDireccion.put(NO_MOVER					, MOVER_DERECHA);
		secuenciaDireccion.put(MOVER_DERECHA			, MOVER_ARRIBA_DERECHA);
		secuenciaDireccion.put(MOVER_ARRIBA_DERECHA		, MOVER_ARRIBA);
		secuenciaDireccion.put(MOVER_ARRIBA				, MOVER_ARRIBA_IZQUIERDA);
		secuenciaDireccion.put(MOVER_ARRIBA_IZQUIERDA	, MOVER_IZQUIERDA);
		secuenciaDireccion.put(MOVER_IZQUIERDA			, MOVER_ABAJO_IZQUIERDA);
		secuenciaDireccion.put(MOVER_ABAJO_IZQUIERDA	, MOVER_ABAJO);
		secuenciaDireccion.put(MOVER_ABAJO				, MOVER_ABAJO_DERECHA);
		secuenciaDireccion.put(MOVER_ABAJO_DERECHA		, NO_MOVER);
		*/
	}
	
	
	private Vector<Coordenada> puntos = new Vector(1000);
	
	public int getLongitud(){
		return puntos.size();
	}
	
	public Coordenada getInicio(){
		return puntos.get(0);
	}

	public Vector<Coordenada> getPuntos(){
		return puntos;
	}
	private  VectorDirector pedirDireccion(){
		
		if (longitud == 50)
			return NO_MOVER;
		if ( (ultimaDireccion.getX() == longitud) && (ultimaDireccion.getY() == 1) ){
			longitud++;
			logger.debug("Longitud: "+longitud);
			ultimaDireccion.setY(0);
			direccionY = -1;
		}

		if (Math.abs(ultimaDireccion.getX()) < longitud ){
			ultimaDireccion.setX(ultimaDireccion.getX() + direccionX );
		}
		else{
			if (Math.abs(ultimaDireccion.getY()) < longitud ){
				ultimaDireccion.setY(ultimaDireccion.getY() + direccionY );
			}
			else{
				if ((direccionX > 0) && (direccionY < 0)){
					direccionX = direccionX * (-1);
					ultimaDireccion.setX(ultimaDireccion.getX() + direccionX );
				}
				else{
					if ((direccionY < 0) && (direccionX < 0)){
						direccionY = direccionY * (-1);
						ultimaDireccion.setY(ultimaDireccion.getY() + direccionY );
					}
					else{
						if( (direccionY > 0) && (direccionX < 0) ){
							direccionX = direccionX * (-1);
							ultimaDireccion.setX(ultimaDireccion.getX() + direccionX );
						}
						else{
							direccionY = direccionY * (-1);
							ultimaDireccion.setY(ultimaDireccion.getY() + direccionY );
						}
					}
				}
			}
		}
		return ultimaDireccion;
	}
	
	public void pedirDireccionReiniciar(){
		direccionX=1;
		direccionY=-1;
		ultimaDireccion.setX(0);
		ultimaDireccion.setY(0);
		longitud = 1;
	}
	
	
	
	void buscar( Coordenada estoy)throws Exception {
		int longitud = 1;
		Coordenada inicio = new Coordenada(estoy);
		puntos.add(estoy);
		Coordenada estoyAnterior = new Coordenada(0,0);
		VectorDirector vMovimiento = pedirDireccion(); 
		
		logger.debug("BUSCANDO");
		int cuentaEstoy = 0;
		while (!vMovimiento.equals(NO_MOVER)){
			if (!mover( estoy, vMovimiento)){
				vMovimiento = pedirDireccion();				
			}
			else{
				estoy.mover(vMovimiento);
				arrayOrigen[estoy.getX()][estoy.getY()]=200;
				puntos.add(new Coordenada(estoy));
				pedirDireccionReiniciar();
				vMovimiento = pedirDireccion();
				cuentaEstoy++;
                                logger.debug(cuentaEstoy);
				if (distanciaInicio(estoy, inicio) < 5 && puntos.size() > 30){
					vMovimiento= NO_MOVER;
					logger.debug("Se encontró criterio de salida.");
				}

			}
		}
		if (ultimaDireccion.equals(NO_MOVER)){
			longitud=1;
		}
	}
	
	double distanciaInicio(Coordenada estoy, Coordenada inicio){
		logger.debug("Estoy: "+estoy+" inicio: "+inicio);
		double resultado = Double.valueOf(Math.pow(Math.pow(estoy.getX()-inicio.getX(), 2) + Math.pow(estoy.getY()-inicio.getY(), 2), 0.5));
		logger.debug(resultado);
		return resultado;
	}
	
	boolean mover(Coordenada estoy, VectorDirector movimiento ){
		boolean resultado = false;
		int desplazamientoX = movimiento.getX()+ estoy.getX();
		int desplazamientoY = movimiento.getY() + estoy.getY();
		
		if (( desplazamientoX < this.ancho ) && (desplazamientoX > 0 ) 
				&& ( desplazamientoY < this.alto) && (desplazamientoY > 0)){
			if (this.arrayOrigen[desplazamientoX][desplazamientoY] >= 255){
				resultado = true;
			}
			
			else{
				this.arrayOrigen[desplazamientoX][desplazamientoY] = 100;
			}
		}
		return resultado;
	}

	public int[][] getArrayOrigen() {
		return arrayOrigen;
	}

	public void setArrayOrigen(int[][] arrayOrigen) {
		this.arrayOrigen = arrayOrigen;
	}

	public int getAncho() {
		return ancho;
	}

	public void setAncho(int ancho) {
		this.ancho = ancho;
	}

	public int getAlto() {
		return alto;
	}

	public void setAlto(int alto) {
		this.alto = alto;
	}
}


